package com.djinfo.work.util;

import java.io.*;
import java.net.SocketException;

import com.djinfo.work.controller.MenuController;
import org.apache.commons.io.FileUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.commons.net.ftp.FTP;
import org.apache.commons.net.ftp.FTPClient;
import org.apache.commons.net.ftp.FTPFile;
import org.apache.commons.net.ftp.FTPReply;

public class FTPClientUtil {
    private static final Log logger = LogFactory.getLog(FTPClientUtil.class);

    private FTPClient ftpclient;
    private boolean bLogin;
    private String host;
    private int port;
    private String username;
    private String password ;

    public FTPClientUtil(String host, int port) throws Exception {
        this(host, port, null, null,false);
    }
    public FTPClientUtil(String host, int port, String username, String password,boolean bLogin)
            throws Exception {
        this.bLogin=false;
        this.host=host;
        this.port=port;
        this.username=username;
        this.password=password;
        ftpclient = new FTPClient();
        ftpclient.setDefaultTimeout(300 * 1000);
        ftpclient.setConnectTimeout(300 * 1000);
        ftpclient.setDataTimeout(300 * 1000);
        if(bLogin) login();
    }
    public boolean login() throws Exception
    {
        try {

            logger.error("ftp开始连接");
            ftpclient.connect(host, port);
            logger.error("连接成功");
            int reply = ftpclient.getReplyCode();
            if (!FTPReply.isPositiveCompletion(reply)) {
                ftpclient.disconnect();
                logger.fatal("FTP服务器拒绝连接");
                throw new Exception("FTP服务器拒绝连接");
            }
            if (username != null) {
                logger.error("ftp开始登陆");
                if (!ftpclient.login(username, password)) {

                    ftpclient.disconnect();
                    logger.fatal("登陆验证失败，请检查账号和密码是否正确");
                    throw new Exception("登陆验证失败，请检查账号和密码是否正确");
                }
                logger.error("ftp登陆成功");
            }
            this.bLogin=true;
        } catch (SocketException e) {
            logger.fatal("无法连接至指定FTP服务器", e);
            throw new Exception(e);
        } catch (IOException e) {
            logger.fatal("无法用指定用户名和密码连接至指定FTP服务器", e);
            throw new Exception(e);
        }
        return this.bLogin;
    }
    /**
     * FTP 文件上传
     * @param pathname 文件名,不带路径
     * @param srcFile  带路径的文件名
     * @return
     * @throws IOException
     */
    public boolean upload(String pathname,String srcFile) throws IOException
    {
        java.io.FileInputStream fs=null;
        try
        {
            fs=new java.io.FileInputStream(srcFile);
            return upload(pathname,fs);
        }
        finally
        {
            if(fs!=null)
                fs.close();
        }
    }
    /**
     *
     * @param  pathname 文件在FTP上存储的绝路径
     * @param input 上传文
     * @throws IOException
     */
    public boolean upload(String pathname, InputStream input)
            throws IOException {
        // 设置被动模式
        ftpclient.enterLocalPassiveMode();
        // 是否是在根目录 下

        ftpclient.setFileType(FTP.BINARY_FILE_TYPE);
        if (pathname.indexOf("/") != -1) {
            String path = pathname.substring(0, pathname.lastIndexOf("/"));
            logger.error("文件路径为："+path);
            CreateDirecroty(path);
            logger.error("创建文件夹成功");
        }
        logger.error("开始上传文件");
       boolean succ =  ftpclient.storeFile(new String(pathname.getBytes(), ftpclient.getControlEncoding()), input);
        if(succ){
            logger.error("上传文件成功");
        }else{
            logger.error("开始上传失败");
        }

        return succ;
    }

    /**
     * 从FTP服务器上下载pathname指定的文件，命名为localName
     *
     * @param pathname
     * @param localName
     * @return
     * @throws Exception
     */
    public boolean download(String pathname, String localName) throws Exception {
        String filename = localName != null ? localName : pathname.substring(pathname.lastIndexOf("/") + 1);

        if (filename == null || filename=="") {
            return false;
        }

        
        // 设置被动模式
        ftpclient.enterLocalPassiveMode();
        // 设置以二进制方式传输
        ftpclient.setFileType(FTP.BINARY_FILE_TYPE);

        if (ftpclient.listFiles(new String(pathname.getBytes(),ftpclient.getControlEncoding())).length == 0) {
            logger.fatal("下载文件不存在");
            throw new Exception("下载文件不存在");
        }
        File tmp = new File(filename + "_tmp"); // 临时文件
        if(!tmp.getParentFile().exists()){
            File part=tmp.getParentFile();
            part.mkdirs();
        }
        File file = new File(filename);
        FileOutputStream output = null;
        boolean flag;
        try {
            output = new FileOutputStream(tmp);
            flag = ftpclient.retrieveFile(new String(pathname.getBytes(),ftpclient.getControlEncoding()), output);
            output.close();
            if (flag) {
                // 下载成功,重命名临时文件。
                tmp.renameTo(file);
            }
        } catch (FileNotFoundException e) {
            logger.fatal("下载文件失败", e);
            throw new Exception(e);
        } finally {
            output.close();
        }

        return flag;
    }

    /**
     * 只删除文件,如果删除空目录请用如下方法： <code>
     * 	getFtpclient().removeDirectory(String pathname)
     * </code> 参考
     * {@link FTPClient FTPClient}
     *
     * @param pathname
     * @return 成功删除返回true,否则返回false(如果文件不存在也返回false)
     * @throws IOException
     */
    public boolean delete(String pathname) throws IOException {
        return ftpclient.deleteFile(new String(pathname.getBytes(),ftpclient.getControlEncoding()));
    }

    /**
     * 改变当前目录至pathname,"/"代表根目录
     *
     * @param pathname
     *            路径名
     * @return 如果改变成功返true否则返回false
     * @throws IOException
     */
    public boolean changeWorkingDirectory(String pathname) throws IOException {
        return ftpclient.changeWorkingDirectory(new String(pathname.getBytes(),ftpclient.getControlEncoding()));
    }

    /**
     * @return {@link FTPClient FTPClient}对象
     */
    public FTPClient getFtpclient() {
        return this.ftpclient;
    }

    /**
     * @param ftpclient
     *            {@link FTPClient FTPClient}对象
     */
    public void setFtpclient(FTPClient ftpclient) {
        this.ftpclient = ftpclient;
    }

    public void close() throws Exception {
        ftpclient.disconnect();
        this.bLogin=false;
    }

    /**
     *
     * @param pathname
     *            要创建的目录路径，可以是相对路径，也可以是绝路径("/"开始)
     * @return 如果成功创建目录返回true，否则返回false(如果目录已存在也返回false)
     * @throws IOException
     */
    public boolean mkdir(String pathname) throws IOException {
        //ftpclient.setControlEncoding("ISO-8859-1");
        //注意编码，如果不编码文件中文目录无法创建
        return ftpclient.makeDirectory(new String(pathname.getBytes(),ftpclient.getControlEncoding()));
    }

    //创建多层目录文件，如果有ftp服务器已存在该文件，则不创建，如果无，则创建
    public boolean CreateDirecroty(String remote) throws IOException {
        boolean success = true;
        String directory = remote + "/";
//        String directory = remote.substring(0, remote.lastIndexOf("/") + 1);
        // 如果远程目录不存在，则递归创建远程服务器目录
        if (!directory.equalsIgnoreCase("/") && !changeWorkingDirectory(new String(directory))) {
            int start = 0;
            int end = 0;
            if (directory.startsWith("/")) {
                start = 1;
            } else {
                start = 0;
            }
            end = directory.indexOf("/", start);
            String path = "";
            String paths = "";
            while (true) {

                String subDirectory = new String(remote.substring(start, end).getBytes("GBK"), "iso-8859-1");
                path = path + "/" + subDirectory;
                if (!existFile(path)) {
                    if (makeDirectory(subDirectory)) {
                        changeWorkingDirectory(subDirectory);
                    } else {
                        logger.debug("创建目录[" + subDirectory + "]失败");
                        changeWorkingDirectory(subDirectory);
                    }
                } else {
                    changeWorkingDirectory(subDirectory);
                }

                paths = paths + "/" + subDirectory;
                start = end + 1;
                end = directory.indexOf("/", start);
                // 检查所有目录是否创建完毕
                if (end <= start) {
                    break;
                }
            }
        }
        return success;
    }

    //判断ftp服务器文件是否存在
    public boolean existFile(String path) throws IOException {
        boolean flag = false;
        FTPFile[] ftpFileArr = ftpclient.listFiles(path);
        if (ftpFileArr.length > 0) {
            flag = true;
        }
        return flag;
    }
    //创建目录
    public boolean makeDirectory(String dir) {
        boolean flag = true;
        try {
            flag = ftpclient.makeDirectory(dir);
            if (flag) {
                logger.debug("创建文件夹" + dir + " 成功！");

            } else {
                logger.debug("创建文件夹" + dir + " 失败！");
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
        return flag;
    }


}
